package com.hyt.it.ogt.pj.service.impl;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import com.hyt.it.ogt.pj.mapper.*;
import com.hyt.it.ogt.pj.model.entity.*;
import com.hyt.it.ogt.pj.model.vo.*;
import com.hyt.it.ogt.pj.service.*;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hyt.core.base.BaseServiceImpl;
import com.hyt.it.ogt.pj.enums.CommonEnums;
import com.hyt.it.ogt.pj.common.ResponseCode;
import com.hyt.it.ogt.pj.enums.MarkTypeEnums;
import com.hyt.it.ogt.pj.enums.MarkmodelEnums;
import com.hyt.it.ogt.pj.enums.PaperItemTypeCode;
import com.hyt.core.util.UUIDUtils;

/**
 * <p>
 * 评卷项目配置 服务实现类
 * </p>
 *
 * @author liy
 * @since 2022-02-28
 */
@Service
public class ProjectSettingServiceImpl extends BaseServiceImpl<ProjectSettingMapper, ProjectSetting> implements IProjectSettingService {
	protected Logger logger = LoggerFactory.getLogger(this.getClass());

	@Autowired
	private ProjectSettingMapper projectSettingMapper;

	@Autowired
	private SubjectMapper subjectMapper;

	@Autowired
	private ProjectMapper projectMapper;

	@Autowired
	private PieceScoreMapper pieceScoreMapper;

	@Autowired
	private TaskMapper taskMapper;


	@Autowired
	private IModeExpertService modeExpertService;

	@Autowired
	private ITaskTimeService taskTimeService;

	@Autowired
	private ITaskService taskService;

	@Autowired
	private IExamExpertService examExpertService;


	@Autowired
	private PaperItemMapper paperItemMapper;





	/**
	 * 查询评卷规则
	 *
	 * @param projectId
	 * @return
	 */
	@Override
	public ProjectSettingVo queryProjectSettingVo(String projectId) {
		ProjectSettingVo projectSettingVo = new ProjectSettingVo();
		projectSettingVo.setProjectId(projectId);
		Project project = projectMapper.selectById(projectId);
		if (null == project) {
			projectSettingVo.setMarkPublish(CommonEnums.TASK_PUBLISH_STATUS_0.getCode());
			return projectSettingVo;
		}

		projectSettingVo.setExamClassfication(project.getExamClassfication());
		projectSettingVo.setMarkPublish(project.getMarkPublish());
		QueryWrapper<ProjectSetting> wrapper = new QueryWrapper<ProjectSetting>();
		wrapper.lambda().eq(ProjectSetting::getProjectId, projectId);
		List<ProjectSetting> projectSettings = projectSettingMapper.selectList(wrapper);

		if (!CollectionUtils.isEmpty(projectSettings)) {
			BeanUtils.copyProperties(projectSettings.get(0), projectSettingVo);
		} else {
			if (CommonEnums.EXAM_CLASSFICATION_2.getCode().equals(project.getExamClassfication())) {
				projectSettingVo.setMarkType(MarkTypeEnums.MARK_TYPE_CROSS.getCode());
			} else {
				projectSettingVo.setMarkType(MarkTypeEnums.MARK_TYPE_FLOW.getCode());
			}
		}
		// List<Task> tasks =
		// taskService.queryTaskList(projectSettingVo.getProjectId());
		// 分组task
		List<Task> tasks = taskService.queryTaskGroupByMarkModel(projectId);
		if (CollectionUtils.isEmpty(tasks)) {
			logger.error("projectId评卷任务不存在:{}", projectId);
			return projectSettingVo;

		}
		Map<String, String> subjectNameMap = new HashMap<>(tasks.size());
		Map<String, String> batchNameMap = new HashMap<>(tasks.size());
		Map<String, String> placeNameMap = new HashMap<>(tasks.size());
		// 按类型分组后的task
		Map<String, Task> tasksMap = dealTask(projectSettingVo, tasks, subjectNameMap, batchNameMap, placeNameMap);

		if (CollectionUtils.isEmpty(tasksMap)) {
			return projectSettingVo;
		}
		projectSettingVo.setOnDisabled(String.valueOf(CommonEnums.ON_DISABLED_0.getCode()));
		if (!CollectionUtils.isEmpty(getPieceScores(tasks)) || CommonEnums.TASK_PUBLISH_STATUS_1.getCode().equals(project.getMarkPublish())) {
			projectSettingVo.setOnDisabled(String.valueOf(CommonEnums.ON_DISABLED_1.getCode()));
		}

		// 无考场只能评卷模式只能按照科目评卷
		if (CommonEnums.EXAM_CLASSFICATION_0.getCode().equals(project.getExamClassfication())) {
			projectSettingVo.setMarkModel(MarkmodelEnums.MARK_MODEL_SUBJECT.getCode());
		}

		// 查询试卷题主观题信息，根据科目分组
		List<PaperResultVo> paperResultVos = paperItemMapper.selectItemNameByProjectId(projectId);
		Map<String, List<PaperResultVo>> paperResultMap = null;
		if (!CollectionUtils.isEmpty(paperResultVos)) {
			paperResultMap = paperResultVos.stream().collect(Collectors.groupingBy(c -> c.getSubjectId()));
		}

		List<ModeExpertVo> modeExpertVos = new ArrayList<>(tasks.size());
		List<TaskTimeVo> taskTimeVos = new ArrayList<>(tasks.size());
		for (Map.Entry<String, Task> entry : tasksMap.entrySet()) {
			// 评卷模式
			modeExpertVos.add(buildModeExpertVo(entry.getKey(), entry.getValue(), subjectNameMap, batchNameMap, placeNameMap, project.getProjectName(), paperResultMap));
		}
		if (!MarkmodelEnums.MARK_MODEL_SUBJECT.getCode().equals(projectSettingVo.getMarkModel())) {
			tasksMap = tasks.stream().collect(Collectors.toMap(Task::getBatchId, Task -> Task, (key1, key2) -> key2));
			for (Map.Entry<String, Task> entry : tasksMap.entrySet()) {
				// 评卷时间设置
				taskTimeVos.add(buildTaskTimeVo(entry.getKey(), entry.getValue(), project, subjectNameMap, projectSettingVo.getMarkModel()));
			}
		} else {
			for (Map.Entry<String, Task> entry : tasksMap.entrySet()) {
				// 评卷时间设置
				taskTimeVos.add(buildTaskTimeVo(entry.getKey(), entry.getValue(), project, subjectNameMap, projectSettingVo.getMarkModel()));
			}
		}
		// 设置已经存在的专家

		dealAlreadyModeExpertVo(projectSettingVo.getProjectId(), projectSettingVo.getMarkModel(), modeExpertVos);
		// 设置已经存在的评卷时间
		dealAlreadyTaskTimeVo(projectSettingVo.getProjectId(), projectSettingVo.getMarkModel(), taskTimeVos);

		projectSettingVo.setTaskTimeVos(taskTimeVos);
		projectSettingVo.setModeExpertVos(modeExpertVos);
		return projectSettingVo;
	}

	@Override
	public ProjectSettingVo queryProjectSettingVo(String projectId, String markModel) {
		ProjectSettingVo projectSettingVo = new ProjectSettingVo();
		projectSettingVo.setProjectId(projectId);
		Project project = projectMapper.selectById(projectId);
		if (null == project) {
			projectSettingVo.setMarkPublish(CommonEnums.TASK_PUBLISH_STATUS_0.getCode());
			return projectSettingVo;
		}
		projectSettingVo.setMarkModel(markModel);
		projectSettingVo.setMarkPublish(project.getMarkPublish());
		// List<Task> tasks = taskService.queryTaskList(projectId, markModel);
		// 分组task
		List<Task> tasks = taskService.queryTaskGroupByMarkModel(projectId);
		if (CollectionUtils.isEmpty(tasks)) {
			logger.error("projectId评卷任务不存在:{}", projectId);
			return projectSettingVo;

		}
		Map<String, String> subjectNameMap = new HashMap<>(tasks.size());
		Map<String, String> batchNameMap = new HashMap<>(tasks.size());
		Map<String, String> placeNameMap = new HashMap<>(tasks.size());
		// 按类型分组后的task
		Map<String, Task> tasksMap = dealTask(projectSettingVo, tasks, subjectNameMap, batchNameMap, placeNameMap);

		if (CollectionUtils.isEmpty(tasksMap)) {
			return projectSettingVo;
		}
		projectSettingVo.setOnDisabled(String.valueOf(CommonEnums.ON_DISABLED_0.getCode()));
		if (!CollectionUtils.isEmpty(getPieceScores(tasks)) || CommonEnums.TASK_PUBLISH_STATUS_1.getCode().equals(project.getMarkPublish())) {
			projectSettingVo.setOnDisabled(String.valueOf(CommonEnums.ON_DISABLED_1.getCode()));
		}

		// 查询试卷题主观题信息，根据科目分组
		List<PaperResultVo> paperResultVos = paperItemMapper.selectItemNameByProjectId(projectId);
		Map<String, List<PaperResultVo>> paperResultMap = null;
		if (!CollectionUtils.isEmpty(paperResultVos)) {
			paperResultMap = paperResultVos.stream().collect(Collectors.groupingBy(c -> c.getSubjectId()));
		}
		List<ModeExpertVo> modeExpertVos = new ArrayList<>(tasks.size());
		List<TaskTimeVo> taskTimeVos = new ArrayList<>(tasks.size());
		for (Map.Entry<String, Task> entry : tasksMap.entrySet()) {
			// 评卷模式
			modeExpertVos.add(buildModeExpertVo(entry.getKey(), entry.getValue(), subjectNameMap, batchNameMap, placeNameMap, project.getProjectName(), paperResultMap));
		}
		if (!MarkmodelEnums.MARK_MODEL_SUBJECT.getCode().equals(projectSettingVo.getMarkModel())) {
			tasksMap = tasks.stream().collect(Collectors.toMap(Task::getBatchId, Task -> Task, (key1, key2) -> key2));
			for (Map.Entry<String, Task> entry : tasksMap.entrySet()) {
				// 评卷时间设置
				taskTimeVos.add(buildTaskTimeVo(entry.getKey(), entry.getValue(), project, subjectNameMap, projectSettingVo.getMarkModel()));
			}
		} else {
			for (Map.Entry<String, Task> entry : tasksMap.entrySet()) {
				// 评卷时间设置
				taskTimeVos.add(buildTaskTimeVo(entry.getKey(), entry.getValue(), project, subjectNameMap, projectSettingVo.getMarkModel()));
			}
		}
		// 设置已经存在的专家
		dealAlreadyModeExpertVo(projectId, markModel, modeExpertVos);
		// 设置已经存在的评卷时间
		dealAlreadyTaskTimeVo(projectId, markModel, taskTimeVos);

		projectSettingVo.setTaskTimeVos(taskTimeVos);
		projectSettingVo.setModeExpertVos(modeExpertVos);
		return projectSettingVo;
	}

	private Map<String, Task> dealTask(ProjectSettingVo projectSettingVo, List<Task> tasks, Map<String, String> subjectNameMap, Map<String, String> batchNameMap, Map<String, String> placeNameMap) {
		Map<String, Task> tasksMap = null;
		Set<String> subjectIds = tasks.stream().map(e -> e.getSubjectId()).collect(Collectors.toSet());
		QueryWrapper<Subject> subjectWrapper = new QueryWrapper<Subject>();
		subjectWrapper.lambda().eq(Subject::getProjectId, projectSettingVo.getProjectId()).in(Subject::getSubjectId, subjectIds);
		List<Subject> subjects = subjectMapper.selectList(subjectWrapper);
		Map<String, Subject> subjectMap = subjects.stream().collect(Collectors.toMap(Subject::getSubjectId, Subject -> Subject, (key1, key2) -> key2));
		if (MarkmodelEnums.MARK_MODEL_BATCH.getCode().equals(projectSettingVo.getMarkModel())) {
			tasksMap = tasks.stream().collect(Collectors.toMap(Task::getBatchId, Task -> Task, (key1, key2) -> key2));
			Map<String, List<Task>> taskMap = tasks.stream().collect(Collectors.groupingBy(c -> c.getBatchId()));
			buildSubjectNameMap(taskMap, subjectMap, subjectNameMap);

		} else if (MarkmodelEnums.MARK_MODEL_ROOM.getCode().equals(projectSettingVo.getMarkModel())) {
			tasksMap = tasks.stream().collect(Collectors.toMap(Task::getRoomId, Task -> Task, (key1, key2) -> key2));
			Map<String, List<Task>> taskMap = tasks.stream().collect(Collectors.groupingBy(c -> c.getRoomId()));
			for (Map.Entry<String, List<Task>> entry : taskMap.entrySet()) {
				Set<String> subjectIdSet = entry.getValue().stream().map(e -> e.getSubjectId()).collect(Collectors.toSet());
				Set<String> subjectNameSet = new HashSet<>();
				for (String subjectId : subjectIdSet) {
					if (CollectionUtils.isEmpty(subjectMap) || null == subjectMap.get(subjectId) || StringUtils.isEmpty(subjectMap.get(subjectId).getSubjectName())) {
						continue;
					}
					subjectNameSet.add(subjectMap.get(subjectId).getSubjectName());
				}
				if (!CollectionUtils.isEmpty(subjectNameSet)) {
					subjectNameMap.put(entry.getKey(), String.join("/", subjectNameSet));
				}

				Set<String> batchNameSet = entry.getValue().stream().map(e -> e.getBatchName()).collect(Collectors.toSet());
				if (!CollectionUtils.isEmpty(batchNameSet)) {
					batchNameMap.put(entry.getKey(), String.join("/", batchNameSet));
				}
				Set<String> placeNameSet = entry.getValue().stream().map(e -> e.getPlaceName()).collect(Collectors.toSet());
				if (!CollectionUtils.isEmpty(placeNameSet)) {
					placeNameMap.put(entry.getKey(), String.join("/", placeNameSet));
				}

			}
		} else {
			tasksMap = tasks.stream().collect(Collectors.toMap(Task::getSubjectId, Task -> Task, (key1, key2) -> key2));
			Map<String, List<Task>> taskMap = tasks.stream().collect(Collectors.groupingBy(c -> c.getSubjectId()));
			buildSubjectNameMap(taskMap, subjectMap, subjectNameMap);
		}
		return tasksMap;
	}

	private void buildSubjectNameMap(Map<String, List<Task>> taskMap, Map<String, Subject> subjectMap, Map<String, String> subjectNameMap) {
		for (Map.Entry<String, List<Task>> entry : taskMap.entrySet()) {
			Set<String> subjectIdSet = entry.getValue().stream().map(e -> e.getSubjectId()).collect(Collectors.toSet());
			Set<String> subjectNameSet = new HashSet<>();
			for (String id : subjectIdSet) {
				if (CollectionUtils.isEmpty(subjectMap) || null == subjectMap.get(id) || StringUtils.isEmpty(subjectMap.get(id).getSubjectName())) {
					continue;
				}
				subjectNameSet.add(subjectMap.get(id).getSubjectName());
			}
			if (!CollectionUtils.isEmpty(subjectNameSet)) {
				subjectNameMap.put(entry.getKey(), String.join("/", subjectNameSet));
			}
		}
	}

	private List<PieceScore> getPieceScores(List<Task> tasks) {
		Set<String> pieceIds = tasks.stream().map(e -> e.getPieceId()).collect(Collectors.toSet());
		QueryWrapper<PieceScore> pieceScoreWrapper = new QueryWrapper<PieceScore>();
		pieceScoreWrapper.lambda().in(PieceScore::getPieceId, pieceIds).eq(PieceScore::getFinish, CommonEnums.PIECCE_SCORE_FINSH_1.getCode());
		return pieceScoreMapper.selectList(pieceScoreWrapper);

	}

	private TaskTimeVo buildTaskTimeVo(String key, Task task, Project project, Map<String, String> subjectNameMap, String markModel) {
		TaskTimeVo taskTimeVo = new TaskTimeVo();
		taskTimeVo.setSubjectId(task.getSubjectId());
		taskTimeVo.setProjectId(task.getProjectId());
		if (!CollectionUtils.isEmpty(subjectNameMap) && null != subjectNameMap.get(key)) {
			taskTimeVo.setSubjectName(subjectNameMap.get(key));
		}
		taskTimeVo.setStartTime(project.getBeginDate());
		taskTimeVo.setEndTime(project.getEndDate());
		// 除了科目按照科目，其他的都按批次
		if (!MarkmodelEnums.MARK_MODEL_SUBJECT.getCode().equals(markModel)) {
			taskTimeVo.setBatchName(task.getBatchName());
			taskTimeVo.setBatchId(task.getBatchId());
			// taskTimeVo.setPlaceId(task.getPlaceId());
			// taskTimeVo.setRoomId(task.getRoomId());
			taskTimeVo.setStartTime(project.getBeginDate());
			taskTimeVo.setEndTime(project.getEndDate());
		}

		return taskTimeVo;

	}

	private ModeExpertVo buildModeExpertVo(String key, Task task, Map<String, String> subjectNameMap, Map<String, String> batchNameMap, Map<String, String> placeNameMap, String projectName,
										   Map<String, List<PaperResultVo>> paperResultMap) {

		ModeExpertVo modeExpertVo = new ModeExpertVo();
		modeExpertVo.setBatchId(task.getBatchId());
		if (!CollectionUtils.isEmpty(batchNameMap) && null != batchNameMap.get(key)) {
			modeExpertVo.setBatchName(batchNameMap.get(key));
		} else {
			modeExpertVo.setBatchName(task.getBatchName());
		}
		modeExpertVo.setPlaceId(task.getPlaceId());
		if (!CollectionUtils.isEmpty(placeNameMap) && null != placeNameMap.get(key)) {
			modeExpertVo.setPlaceName(placeNameMap.get(key));
		}

		modeExpertVo.setRoomId(task.getRoomId());
		modeExpertVo.setRoomName(task.getRoomName());
		modeExpertVo.setSubjectId(task.getSubjectId());
		if (!CollectionUtils.isEmpty(subjectNameMap) && null != subjectNameMap.get(key)) {
			modeExpertVo.setSubjectName(subjectNameMap.get(key));
		}
		modeExpertVo.setProjectId(task.getProjectId());
		modeExpertVo.setProjectName(projectName);

		// 统计评卷模式列表题目汇总和题目信息
		if (!CollectionUtils.isEmpty(paperResultMap) && !CollectionUtils.isEmpty(paperResultMap.get(task.getSubjectId()))) {
			Set<String> topicTypes = paperResultMap.get(task.getSubjectId()).stream()
					.filter(e -> !"0".equals(e.getParentId()) && StringUtils.isNotEmpty(PaperItemTypeCode.getMsgByCode(e.getItemType()))).map(e -> PaperItemTypeCode.getMsgByCode(e.getItemType()))
					.collect(Collectors.toSet());
			List<String> topicTypeList = paperResultMap.get(task.getSubjectId()).stream().filter(e -> !"0".equals(e.getParentId())).map(e -> e.getItemType()).collect(Collectors.toList());
			if (!CollectionUtils.isEmpty(topicTypeList)) {
				modeExpertVo.setTopicTotal(topicTypeList.size());
			}
			if (!CollectionUtils.isEmpty(topicTypes)) {
				modeExpertVo.setTopicTypes(topicTypes);
			}
		}

		return modeExpertVo;
	}

	private void dealAlreadyModeExpertVo(String projectId, String markModel, List<ModeExpertVo> modeExpertVos) {
		QueryWrapper<ProjectSetting> wrapper = new QueryWrapper<ProjectSetting>();
		wrapper.lambda().eq(ProjectSetting::getProjectId, projectId).eq(ProjectSetting::getMarkModel, markModel);
		List<ProjectSetting> projectSettings = projectSettingMapper.selectList(wrapper);

		if (CollectionUtils.isEmpty(projectSettings)) {
			return;
		}
		List<ModeExpertVo> modeExpertList = modeExpertService.queryModeExpertList(projectId, markModel);
		if (CollectionUtils.isEmpty(modeExpertList)) {
			return;
		}
		//设置专家的已评卷数
		List<TaskNumberVo> taskNumberVos = taskMapper.queryFinishTaskPieceScore(projectId);
		List<Task> tasks = taskMapper.queryTask(projectId);
		// 0：按科目评卷，1：按批次评卷，2：按考场评卷
		if (MarkmodelEnums.MARK_MODEL_SUBJECT.getCode().equals(markModel)) {
			Map<String, ModeExpertVo> modeExpertMap = modeExpertList.stream().collect(Collectors.toMap(ModeExpertVo::getSubjectId, ModeExpertVo -> ModeExpertVo, (key1, key2) -> key2));
			for (ModeExpertVo vo : modeExpertVos) {
				ModeExpertVo modeExpertVo = modeExpertMap.get(vo.getSubjectId());
				if (modeExpertVo == null) {
					continue;
				}
				vo.setPaperTotal(0);
				vo.setNumber(modeExpertVo.getNumber());
				vo.setAutoFlag(modeExpertVo.getAutoFlag());
				if (!CollectionUtils.isEmpty(tasks)) {
					Map<String, List<Task>> taskMap = tasks.stream().collect(Collectors.groupingBy(c -> c.getSubjectId()));
					vo.setPaperTotal(taskMap.get(vo.getSubjectId()).size());
				}
				if (MarkTypeEnums.MARK_TYPE_CROSS.getCode().equals(projectSettings.get(0).getMarkType()) && null != modeExpertVo.getNumber() && modeExpertVo.getNumber().intValue() > 0) {
					Map<String, List<Task>> taskMap = tasks.stream().collect(Collectors.groupingBy(c -> c.getSubjectId()));
					vo.setPaperTotal(taskMap.get(vo.getSubjectId()).size() * modeExpertVo.getNumber().intValue());
				}
				vo.setId(modeExpertVo.getId());
				//处理已评卷量逻辑
				Map<String,List<TaskNumberVo>> taskNumberMap = taskNumberVos.stream().collect(Collectors.groupingBy(c -> c.getExpertId() + c.getSubjectId()));
                if(!CollectionUtils.isEmpty(modeExpertVo.getExamExpertVos()) && MapUtils.isNotEmpty(taskNumberMap)) {
                    for (ExamExpertVo examExpertVo : modeExpertVo.getExamExpertVos()) {
                    	if(CollectionUtils.isEmpty(taskNumberMap.get(examExpertVo.getExpertId() + vo.getSubjectId()))){
                    		continue;
						}
                        examExpertVo.setAlreadyQuantity(taskNumberMap.get(examExpertVo.getExpertId() + vo.getSubjectId()).size());
                    }
                }
				vo.setExamExpertVos(modeExpertVo.getExamExpertVos());

			}
		} else if (MarkmodelEnums.MARK_MODEL_BATCH.getCode().equals(markModel)) {
			Map<String, ModeExpertVo> modeExpertMap = modeExpertList.stream().collect(Collectors.toMap(ModeExpertVo::getBatchId, ModeExpertVo -> ModeExpertVo, (key1, key2) -> key2));

			for (ModeExpertVo vo : modeExpertVos) {
				ModeExpertVo modeExpertVo = modeExpertMap.get(vo.getBatchId());
				if (modeExpertVo == null) {
					continue;
				}
				vo.setPaperTotal(0);
				if (!CollectionUtils.isEmpty(tasks)) {
					Map<String, List<Task>> taskMap = tasks.stream().collect(Collectors.groupingBy(c -> c.getBatchId()));
					vo.setPaperTotal(taskMap.get(vo.getBatchId()).size());
				}
				if (MarkTypeEnums.MARK_TYPE_CROSS.getCode().equals(projectSettings.get(0).getMarkType()) && null != modeExpertVo.getNumber() && modeExpertVo.getNumber().intValue() > 0) {
					Map<String, List<Task>> taskMap = tasks.stream().collect(Collectors.groupingBy(c -> c.getBatchId()));
					vo.setPaperTotal(taskMap.get(vo.getBatchId()).size() * modeExpertVo.getNumber().intValue());
				}
				vo.setNumber(modeExpertVo.getNumber());
				vo.setId(modeExpertVo.getId());
				//处理已评卷量逻辑
				Map<String,List<TaskNumberVo>> taskNumberMap = taskNumberVos.stream().collect(Collectors.groupingBy(c -> c.getExpertId() + c.getBatchId()));
                if(!CollectionUtils.isEmpty(modeExpertVo.getExamExpertVos()) && MapUtils.isNotEmpty(taskNumberMap)) {
                    for (ExamExpertVo examExpertVo : modeExpertVo.getExamExpertVos()) {
						if(CollectionUtils.isEmpty(taskNumberMap.get(examExpertVo.getExpertId() + vo.getSubjectId()))){
							continue;
						}
                        examExpertVo.setAlreadyQuantity(taskNumberMap.get(examExpertVo.getExpertId() + vo.getBatchId()).size());
                    }
                }
				vo.setExamExpertVos(modeExpertVo.getExamExpertVos());

			}
		} else if (MarkmodelEnums.MARK_MODEL_ROOM.getCode().equals(markModel)) {
			Map<String, ModeExpertVo> modeExpertMap = modeExpertList.stream().collect(Collectors.toMap(ModeExpertVo::getRoomId, ModeExpertVo -> ModeExpertVo, (key1, key2) -> key2));

			for (ModeExpertVo vo : modeExpertVos) {
				ModeExpertVo modeExpertVo = modeExpertMap.get(vo.getRoomId());
				if (modeExpertVo == null) {
					continue;
				}
				vo.setPaperTotal(0);
				if (!CollectionUtils.isEmpty(tasks)) {
					Map<String, List<Task>> taskMap = tasks.stream().collect(Collectors.groupingBy(c -> c.getRoomId()));
					vo.setPaperTotal(taskMap.get(vo.getRoomId()).size());
				}
				if (MarkTypeEnums.MARK_TYPE_CROSS.getCode().equals(projectSettings.get(0).getMarkType()) && null != modeExpertVo.getNumber() && modeExpertVo.getNumber().intValue() > 0) {
					Map<String, List<Task>> taskMap = tasks.stream().collect(Collectors.groupingBy(c -> c.getRoomId()));
					vo.setPaperTotal(taskMap.get(vo.getRoomId()).size() * modeExpertVo.getNumber().intValue());
				}
				vo.setNumber(modeExpertVo.getNumber());
				vo.setId(modeExpertVo.getId());
				//处理已评卷量逻辑
				Map<String,List<TaskNumberVo>> taskNumberMap = taskNumberVos.stream().collect(Collectors.groupingBy(c -> c.getExpertId() + c.getRoomId()));
                if(!CollectionUtils.isEmpty(modeExpertVo.getExamExpertVos()) && MapUtils.isNotEmpty(taskNumberMap)) {
                    for (ExamExpertVo examExpertVo : modeExpertVo.getExamExpertVos()) {
						if(CollectionUtils.isEmpty(taskNumberMap.get(examExpertVo.getExpertId() + vo.getSubjectId()))){
							continue;
						}
                        examExpertVo.setAlreadyQuantity(taskNumberMap.get(examExpertVo.getExpertId() + vo.getRoomId()).size());
                    }
                }
				vo.setExamExpertVos(modeExpertVo.getExamExpertVos());

			}
		}

	}

	private void dealAlreadyTaskTimeVo(String projectId, String markModel, List<TaskTimeVo> taskTimeVos) {
		QueryWrapper<ProjectSetting> wrapper = new QueryWrapper<ProjectSetting>();
		wrapper.lambda().eq(ProjectSetting::getProjectId, projectId).eq(ProjectSetting::getMarkModel, markModel);
		List<ProjectSetting> projectSettings = projectSettingMapper.selectList(wrapper);

		if (CollectionUtils.isEmpty(projectSettings)) {
			return;
		}
		List<TaskTimeVo> taskTimeList = taskTimeService.queryTaskTimeList(projectId, markModel);
		if (CollectionUtils.isEmpty(taskTimeList)) {
			return;
		}
		// 0：按科目评卷，1：按批次评卷，2：按考场评卷
		if (MarkmodelEnums.MARK_MODEL_SUBJECT.getCode().equals(markModel)) {
			Map<String, TaskTimeVo> taskTimeMap = taskTimeList.stream().collect(Collectors.toMap(TaskTimeVo::getSubjectId, TaskTimeVo -> TaskTimeVo, (key1, key2) -> key2));
			for (TaskTimeVo vo : taskTimeVos) {
				TaskTimeVo taskTimeVo = taskTimeMap.get(vo.getSubjectId());
				if (taskTimeVo == null) {
					continue;
				}
				vo.setId(taskTimeVo.getId());
				vo.setStartTime(taskTimeVo.getStartTime());
				vo.setEndTime(taskTimeVo.getEndTime());

			}
		} else if (MarkmodelEnums.MARK_MODEL_BATCH.getCode().equals(markModel) || MarkmodelEnums.MARK_MODEL_ROOM.getCode().equals(markModel)) {
			Map<String, TaskTimeVo> taskTimeMap = taskTimeList.stream().collect(Collectors.toMap(TaskTimeVo::getBatchId, TaskTimeVo -> TaskTimeVo, (key1, key2) -> key2));
			for (TaskTimeVo vo : taskTimeVos) {
				TaskTimeVo taskTimeVo = taskTimeMap.get(vo.getBatchId());
				if (taskTimeVo == null) {
					continue;
				}
				vo.setId(taskTimeVo.getId());
				vo.setStartTime(taskTimeVo.getStartTime());
				vo.setEndTime(taskTimeVo.getEndTime());

			}
		}

	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean saveProjectSetting(ProjectSettingVo projectSettingVo) {

		// 处理设置，先删除再保存
		QueryWrapper<ProjectSetting> projectSettingWrapper = new QueryWrapper<ProjectSetting>();
		projectSettingWrapper.lambda().eq(ProjectSetting::getProjectId, projectSettingVo.getProjectId());
		projectSettingMapper.delete(projectSettingWrapper);
		ProjectSetting projectSetting = new ProjectSetting();
		BeanUtils.copyProperties(projectSettingVo, projectSetting);
		projectSetting.setId(UUIDUtils.newSortUUID());
		projectSettingMapper.insert(projectSetting);
		// 处理设置模式 先删除再保存
		QueryWrapper<ModeExpert> modeExpertWrapper = new QueryWrapper<ModeExpert>();
		modeExpertWrapper.lambda().eq(ModeExpert::getProjectId, projectSetting.getProjectId());
		modeExpertService.remove(modeExpertWrapper);

		List<ModeExpertVo> modeExpertVos = projectSettingVo.getModeExpertVos();
		List<ModeExpert> modeExperts = new ArrayList<>(modeExpertVos.size());
		List<ExamExpertVo> examExpertVos = new ArrayList<>(modeExpertVos.size());
		for (ModeExpertVo modeExpertVo : modeExpertVos) {
			modeExpertVo.setProjectId(projectSettingVo.getProjectId());
			ModeExpert modeExpert = new ModeExpert();
			BeanUtils.copyProperties(modeExpertVo, modeExpert);
			if (MarkmodelEnums.MARK_MODEL_SUBJECT.getCode().equals(projectSetting.getMarkModel())) {
				modeExpert.setPlaceId("");
				modeExpert.setRoomId("");
				modeExpert.setBatchId("");
			} else if (MarkmodelEnums.MARK_MODEL_BATCH.getCode().equals(projectSetting.getMarkModel())) {
				modeExpert.setPlaceId("");
				modeExpert.setRoomId("");
			}
			modeExpert.setId(UUIDUtils.newSortUUID());
			modeExperts.add(modeExpert);
			for (ExamExpertVo examExpertVo : modeExpertVo.getExamExpertVos()) {
				examExpertVo.setModeExpertId(modeExpert.getId());
			}
			examExpertVos.addAll(modeExpertVo.getExamExpertVos());
		}
		modeExpertService.saveBatch(modeExperts);

		// 保存专家设置 先删除再保存
		QueryWrapper<ExamExpert> examExpertWrapper = new QueryWrapper<ExamExpert>();
		examExpertWrapper.lambda().eq(ExamExpert::getProjectId, projectSetting.getProjectId());
		examExpertService.remove(examExpertWrapper);
		List<ExamExpert> examExperts = new ArrayList<>(examExpertVos.size());
		for (ExamExpertVo examExpertVo : examExpertVos) {
			examExpertVo.setProjectId(projectSettingVo.getProjectId());
			ExamExpert examExpert = new ExamExpert();
			BeanUtils.copyProperties(examExpertVo, examExpert);
			examExpert.setId(UUIDUtils.newSortUUID());
			examExperts.add(examExpert);
		}
		examExpertService.saveBatch(examExperts);
		// 处理评卷时间 先删除再保存
		QueryWrapper<TaskTime> taskTimeWrapper = new QueryWrapper<TaskTime>();
		taskTimeWrapper.lambda().eq(TaskTime::getProjectId, projectSetting.getProjectId());
		taskTimeService.remove(taskTimeWrapper);

		List<TaskTimeVo> taskTimeVos = projectSettingVo.getTaskTimeVos();
		List<TaskTime> taskTimes = new ArrayList<>(taskTimeVos.size());
		for (TaskTimeVo taskTimeVo : taskTimeVos) {
			taskTimeVo.setProjectId(projectSettingVo.getProjectId());
			TaskTime taskTime = new TaskTime();
			BeanUtils.copyProperties(taskTimeVo, taskTime);
			taskTime.setId(UUIDUtils.newSortUUID());
			// 评论时间除了按科目其他的都是按批次
			if (MarkmodelEnums.MARK_MODEL_SUBJECT.getCode().equals(projectSetting.getMarkModel())) {
				taskTime.setPlaceId("");
				taskTime.setRoomId("");
				taskTime.setBatchId("");
			} else {
				taskTime.setPlaceId("");
				taskTime.setRoomId("");
			}
			taskTimes.add(taskTime);
		}
		taskTimeService.saveBatch(taskTimes);
		return true;
	}

	@Override
	public ProjectAddressVo queryTwoDimensionalCode(String projectId) {
		Project project = projectMapper.selectById(projectId);
		if (null == project) {
			return null;
		}
		ProjectAddressVo projectAddressVo = new ProjectAddressVo();
		projectAddressVo.setShowTwoDimensional(false);
		projectAddressVo.setBeginDate(project.getBeginDate());
		projectAddressVo.setEndDate(project.getEndDate());
		projectAddressVo.setProjectName(project.getProjectName());

		QueryWrapper<Task> taskWrapper = new QueryWrapper<Task>();
		taskWrapper.lambda().eq(Task::getProjectId, projectId);
		List<Task> tasks = taskMapper.selectList(taskWrapper);
		if (CollectionUtils.isEmpty(tasks)) {
			return projectAddressVo;
		}
		Set<String> subjectIds = tasks.stream().filter(e -> StringUtils.isNotEmpty(e.getSubjectId())).map(e -> e.getSubjectId()).collect(Collectors.toSet());
		String batchName = StringUtils.join(tasks.stream().filter(e -> StringUtils.isNotEmpty(e.getBatchName())).map(e -> e.getBatchName()).collect(Collectors.toSet()), "、");
		if (!CollectionUtils.isEmpty(subjectIds)) {
			QueryWrapper<Subject> subjectWrapper = new QueryWrapper<Subject>();
			subjectWrapper.lambda().eq(Subject::getProjectId, projectId).in(Subject::getSubjectId, subjectIds);
			List<Subject> subjects = subjectMapper.selectList(subjectWrapper);
			if (!CollectionUtils.isEmpty(subjects)) {
				String subjectName = StringUtils.join(subjects.stream().filter(e -> StringUtils.isNotEmpty(e.getSubjectName())).map(e -> e.getSubjectName()).collect(Collectors.toSet()), "、");
				projectAddressVo.setSubjectName(subjectName);
			}
		}
		projectAddressVo.setBatchName(batchName);
		QueryWrapper<ProjectSetting> wrapper = new QueryWrapper<ProjectSetting>();
		wrapper.lambda().eq(ProjectSetting::getProjectId, projectId);
		List<ProjectSetting> projectSettings = projectSettingMapper.selectList(wrapper);
		if (CollectionUtils.isEmpty(projectSettings)) {
			return projectAddressVo;
		}

		if (StringUtils.isNotEmpty(projectSettings.get(0).getMobile()) && CommonEnums.CLIENT_MARK_1.getCode().equals(Integer.valueOf(projectSettings.get(0).getMobile()))) {
			projectAddressVo.setShowTwoDimensional(true);
		}
		return projectAddressVo;
	}

	@Override
	public String checkMarkPublish(ProjectSettingVo projectSettingVo) {
		// 发布状态开启时不允许编辑
		Project project = projectMapper.selectById(projectSettingVo.getProjectId());

		if (null != project && null != project.getMarkPublish() && CommonEnums.TASK_PUBLISH_STATUS_1.getCode().equals(project.getMarkPublish())) {
			return ResponseCode.codeMap.get(ResponseCode.PUBLISH_TASK_NOT_EDIT);
		}

		List<PieceScore> pieceScoresList = getPieceScores(projectSettingVo);
//		Map<String, List<PieceScore>> pieceScoreMap = pieceScoresList.stream().collect(Collectors.groupingBy(c -> c.getSubjectId() + c.getUserId()));
		QueryWrapper<ProjectSetting> wrapper = new QueryWrapper<ProjectSetting>();
		wrapper.lambda().eq(ProjectSetting::getProjectId, projectSettingVo.getProjectId());
		List<ProjectSetting> projectSettings = projectSettingMapper.selectList(wrapper);
		if (!CollectionUtils.isEmpty(pieceScoresList) && !CollectionUtils.isEmpty(projectSettings) && !projectSettings.get(0).getMarkType().equals(projectSettingVo.getMarkType())
				&& !projectSettings.get(0).getMarkModel().equals(projectSettingVo.getMarkModel())) {

			return ResponseCode.codeMap.get(ResponseCode.PUBLISH_TASK_HAVE_SCORE_NOT_EDIT);
		}

		if (CollectionUtils.isEmpty(projectSettingVo.getModeExpertVos())) {
			return ResponseCode.codeMap.get(ResponseCode.MARK_MODEL_NOT_EMPRY);
		}
		for (ModeExpertVo modeExpertVo : projectSettingVo.getModeExpertVos()) {
			// 校验评卷量：校验列表中专家评卷量是否已设置，若未设置，则提示“有专家评卷量为空，请进行设置！”；
			if (null == modeExpertVo.getPaperTotal() || modeExpertVo.getPaperTotal().intValue() == 0) {
				return ResponseCode.codeMap.get(ResponseCode.EXPERT_NUMBER_IS_EMPTY);
			}

			if (CollectionUtils.isEmpty(modeExpertVo.getExamExpertVos())) {
				return ResponseCode.codeMap.get(ResponseCode.EXAM_EXPERT_IS_EMPTY);
			}

			// 校验评卷总量：校验列表中专家的评卷量总和是否等于评卷总量，若不等于，则提示“专家评卷量总和不等于评卷总量，请调整！”；
			if (MarkTypeEnums.MARK_TYPE_FLOW.getCode().equals(projectSettingVo.getMarkType())) {
				Integer total = modeExpertVo.getExamExpertVos().stream().filter(e -> null != e.getQuantity()).collect(Collectors.summingInt(ExamExpertVo::getQuantity));
				if (!total.equals(modeExpertVo.getPaperTotal())) {
					return ResponseCode.codeMap.get(ResponseCode.MARK_TOTAL_NOT_TOTAL_NUMBER);
				}
			} else if (MarkTypeEnums.MARK_TYPE_CROSS.getCode().equals(projectSettingVo.getMarkType())) {
				if (null == modeExpertVo.getNumber()) {
					return ResponseCode.codeMap.get(ResponseCode.MARK_TOTAL_NOT_EMPTY);
				}
				Integer total = modeExpertVo.getExamExpertVos().stream().filter(e -> null != e.getQuantity()).collect(Collectors.summingInt(ExamExpertVo::getQuantity));
				if (!total.equals(modeExpertVo.getPaperTotal().intValue())) {
					return ResponseCode.codeMap.get(ResponseCode.EXPERT_MARK_TOTAL_NOT_TOTAL_NUMBER);
				}

			}

			// 校验每位专家的评卷量是否小于试卷总量，若不小于，则提示“***专家评卷任务量大于试卷总量，请调整！
			for (ExamExpertVo examExpertVo : modeExpertVo.getExamExpertVos()) {
				if (null == examExpertVo.getQuantity()) {
					return examExpertVo.getExpertName() + "有专家评卷量为空，请进行设置";
				}

				if (modeExpertVo.getPaperTotal().intValue() < examExpertVo.getQuantity().intValue()) {
					return examExpertVo.getExpertName() + "专家评卷任务量大于试卷总量，请调整";
				}
				// 编辑评卷量校验：若评卷专家已完成N份试卷评分，则在编辑此专家评卷量时，设置的评卷量不得少于N份，否则提示“***专家已完成N份试卷评分，评卷量设置不得少于N份，请调整！”。
//				if (CollectionUtils.isEmpty(pieceScoreMap) || CollectionUtils.isEmpty(pieceScoreMap.get(modeExpertVo.getSubjectId() + examExpertVo.getExpertId()))) {
//					continue;
//				}
//				List<PieceScore> pieceScores = pieceScoreMap.get(modeExpertVo.getSubjectId() + examExpertVo.getExpertId());
//				if (examExpertVo.getQuantity().intValue() < pieceScores.size()) {
//					return examExpertVo.getExpertName() + "专家已完成" + pieceScores.size() + "份试卷评分，评卷量设置不得少于" + pieceScores.size() + "份，请调整";
//				}

			}
		}
		if (!CollectionUtils.isEmpty(projectSettingVo.getTaskTimeVos())) {
			for (TaskTimeVo taskTimeVo : projectSettingVo.getTaskTimeVos()) {
				if (null != taskTimeVo.getStartTime() && null != taskTimeVo.getEndTime() && DateUtils.truncatedCompareTo(taskTimeVo.getStartTime(), taskTimeVo.getEndTime(), Calendar.SECOND) > 1) {
					return ResponseCode.codeMap.get(ResponseCode.MARK_TASK_TIME_ERROR);

				}
			}
		}

		return String.valueOf(ResponseCode.SUCCESS);
	}

	private List<PieceScore> getPieceScores(ProjectSettingVo projectSettingVo) {
		QueryWrapper<Task> taskWrapper = new QueryWrapper<Task>();
		taskWrapper.lambda().eq(Task::getProjectId, projectSettingVo.getProjectId());
		List<Task> tasks = taskMapper.selectList(taskWrapper);
		if (CollectionUtils.isEmpty(tasks)) {
			return null;
		}
		Set<String> pieceIds = tasks.stream().map(e -> e.getPieceId()).collect(Collectors.toSet());
		QueryWrapper<PieceScore> pieceScoreWrapper = new QueryWrapper<PieceScore>();
		pieceScoreWrapper.lambda().in(PieceScore::getPieceId, pieceIds).eq(PieceScore::getFinish, CommonEnums.PIECCE_SCORE_FINSH_1.getCode());
		List<PieceScore> pieceScores = pieceScoreMapper.selectList(pieceScoreWrapper);
		return pieceScores;
	}



}
